package com.jandar.table;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;

import com.jandar.table.config.Column;
import com.jandar.table.config.ColumnTypeInfo;
import com.jandar.table.config.Department;
import com.jandar.table.config.Id;
import com.jandar.table.config.IdGeneratorInfo;
import com.jandar.table.config.Name;
import com.jandar.table.config.Table;
import com.jandar.table.config.Tables;
import com.jandar.table.config.UniqueInfo;
import com.jandar.util.ExceptionUtils;

/**
 * 数据库表XML配置文件解析器。
 * 
 * @author pqj
 * @version 2009-6-2
 */
public class TableHander extends DefaultHandler {
	private static final String TABLE = "table";
	private static final String DEPARTMENT = "department";
	private static final String NAME = "name";
	private static final String ID = "id";
	private static final String COLUMN = "column";
	
	//private Locator locator;
	private Map<String, Table> tableCfgMap = new HashMap<String, Table>();
	private Tables tables = new Tables();
	private String curText = null;
	private Table table = null;
	private Department department = null;
	private Id id = null;
	private Name name = null;
	private Column column = null;
	private List<Id> ids = null;
	private List<Column> columns = null;

	@Override
	public void characters(char[] ch, int start, int length) throws SAXException {
		curText = new String(ch, start, length).trim();
	}

	@Override
	public void endDocument() throws SAXException {
	}

	@Override
	public void endElement(String uri, String localName, String qName) throws SAXException {
		if (TABLE.equals(qName)) {
			table.setId(ids);
			table.setColumn(columns);
			tables.getTable().add(table);
			tableCfgMap.put(table.getName().getValue(), table);
		} else if (DEPARTMENT.equals(qName)) {
			department.setTitle(curText);
			table.setDepartment(department);
		} else if (NAME.equals(qName)) {
			name.setTitle(curText);
			table.setName(name);
		} else if (ID.equals(qName)) {
			id.setTitle(curText);
			ids.add(id);
		} else if (COLUMN.equals(qName)) {
			column.setTitle(curText);
			columns.add(column);
		}
	}

	@Override
	public void endPrefixMapping(String prefix) throws SAXException {
	}

	@Override
	public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
	}

	@Override
	public void processingInstruction(String target, String data) throws SAXException {
	}

	@Override
	public void setDocumentLocator(Locator locator) {
		//this.locator = locator;
	}

	@Override
	public void skippedEntity(String name) throws SAXException {
	}

	@Override
	public void startDocument() throws SAXException {
	}

	@Override
	public void startElement(String uri, String localName, String qName, Attributes attr) throws SAXException {
		if (TABLE.equals(qName)) {
			table = new Table();
			ids = new ArrayList<Id>();
			columns = new ArrayList<Column>();
		} else if (DEPARTMENT.equals(qName)) {
			department = new Department();
		} else if (NAME.equals(qName)) {
			name = new Name();
			name.setValue(attr.getValue("value"));
		} else if (ID.equals(qName)) {
			id = new Id();
			id.setValue(attr.getValue("value"));
			id.setType(ColumnTypeInfo.valueOf(attr.getValue("type")));
			String uniqueStr = attr.getValue("unique");
			if (uniqueStr != null && !"".equals(uniqueStr)) {
				id.setUnique(UniqueInfo.valueOf(uniqueStr));
			}
			id.setFormat(attr.getValue("format"));
			id.setGenerator(IdGeneratorInfo.valueOf(attr.getValue("generator")));
			id.setSequence(attr.getValue("sequence"));
		} else if (COLUMN.equals(qName)) {
			column = new Column();
			column.setValue(attr.getValue("value"));
			column.setType(ColumnTypeInfo.valueOf(attr.getValue("type")));
			String uniqueStr = attr.getValue("unique");
			if (uniqueStr != null && !"".equals(uniqueStr)) {
				column.setUnique(UniqueInfo.valueOf(uniqueStr));
			}
			column.setFormat(attr.getValue("format"));
		}
	}

	@Override
	public void startPrefixMapping(String prefix, String uri) throws SAXException {
	}

	
	@Override
	public void error(SAXParseException e) throws SAXException {
		ExceptionUtils.error(e);
	}

	@Override
	public void fatalError(SAXParseException e) throws SAXException {
		ExceptionUtils.error(e);
		throw e;
	}

	@Override
	public void warning(SAXParseException e) throws SAXException {
		ExceptionUtils.error(e);
	}

	public Map<String, Table> getTableCfgMap() {
		return tableCfgMap;
	}

	public Tables getTables() {
		return tables;
	}
}
